package cn.wolfcode.wolf2w.interceptor;

import cn.wolfcode.wolf2w.annotation.RequireLogin;
import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.redis.IUserInfoRedisService;
import cn.wolfcode.wolf2w.util.JsonResult;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;



@Component
public class CheckLoginInterceptor implements HandlerInterceptor {

    @Autowired
    private IUserInfoRedisService userInfoRedisService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {

        /**
         * handlerMethod 请求映射方法信息(类名, 方法名, 方法参数, 方法注解......)封装对象
         *
         *
         * 操作流程:
         *  1:springmvc启动的时候, 对所有的controller类里面所有请求映射方法进行解析9, 将每个映射方法解析出的信息封装成一个个对象:
         *  handlerMethod
         *  2:spring容器为了方便管理这些对象, 创建出一个类型与map集合对象对所有的handlerMethod对象进行存储
         *      map的key: 请求映射路径, map的 value : 请求映射方法信息对象 handlerMethod
         *
         *      {
         *          "/user/currentUser"  currentUser的映射方法信息对象HandlerMethod
         *
         *      }
         *  3:当浏览器发起请求时候, 拦截器获取并解析请求, 可以得到url路径: 假设是"/user/currentUser"
         *      通过map获取/user/currentUser对应的handlerMehtod的对象, 调用preHandle方法将handlerMehtod传入
         *
         *      HandlerMethod handler = map.get("/user/currentUser")
         *      xxx.preHandle(request, reponse, handler)
         */


        //拦截器的preHandle 的参数 Object handler 总共有三种类型
        //1:静态资源请求类型
        //2:动态请求(请求映射方法)类型 handlerMethod
        //3:跨域请求类型

        //解决拦截器跨域问题
        //instanceof 判断左边对象是否为右边类的实例
        if (!(handler instanceof HandlerMethod)){
            return true;
        }

        HandlerMethod hm = (HandlerMethod) handler;

        String token = request.getHeader("token");

        UserInfo user = userInfoRedisService.getUserInfoByToken(token);

        //判断当前请求映射方法头顶是否有@requireLogin
        if (hm.hasMethodAnnotation(RequireLogin.class)){
            if (user == null){

                response.setContentType("application/json;charset=utf-8");
                response.getWriter().write(JSON.toJSONString(JsonResult.noLogin()));

                return false;

            }
        }
        return true;
    }
}
